/*
 * {comment of class}
 *
 * @author (C) <a href="http://www.carfield.com.hk">Carfield Yim </a>, 2004
 */
package hk.com.carfield.core;

import hk.com.carfield.action.Body;
import hk.com.carfield.action.Default;
import hk.com.carfield.action.Edit;
import hk.com.carfield.action.Plain;
import hk.com.carfield.action.process.New;
import hk.com.carfield.action.process.Process;
import hk.com.carfield.action.process.Rename;
import hk.com.carfield.action.process.Session;
import hk.com.carfield.action.process.Trash;
import hk.com.carfield.action.process.Upload;
import hk.com.carfield.web.Request;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public final class ActionManager {
	final private static Map<String, Class<?>> codeClassMap = new HashMap<String, Class<?>>();

	final private static List<Class<?>> processes;
	static {
		processes = new ArrayList<Class<?>>();
		final Process[] adminBodies = { new hk.com.carfield.action.process.Edit(), new New(), new Rename(),
				new Upload(), new Session(), new Trash() };
		for (int i = 0; i < adminBodies.length; i++) {
			processes.add(adminBodies[i].getClass());
			codeClassMap.put(adminBodies[i].actionCode(), adminBodies[i].getClass());
		}

		final Body[] functionBodies = { new Edit(), };
		for (int i = 0; i < functionBodies.length; i++) {
			codeClassMap.put(functionBodies[i].actionCode(), functionBodies[i].getClass());
		}
	}

	public static Body getBody(final Context c, final Request req, final File l) {
		try {
			final Class<?> type = getType(req);
			final Body body;
			if (type != null && !processes.contains(type)) {
				body = (Body) type.newInstance();
			} else {
				body = new Default();
			}

			if (processes.contains(type) && type != null) {
				final Process process = (Process) type.newInstance();
				if (process.adminOnly() && !req.isAdminEnable()) {
					return Plain.forbiddenBody(l, c);
				} else {
					File result = process.process(c, req, l);
					if (!c.config.displayFilter().accept(result.getParentFile(), result.getName())) {
						result = result.getParentFile();
					}
					body.init(c, req, result);
				}
			} else {
				body.init(c, req, l);
			}
			return body;
		} catch (final IOException e) {
			throw new RuntimeException(e);
		} catch (final InstantiationException e) {
			throw new RuntimeException(e);
		} catch (final IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}

	private static Class<?> getType(final Request req) {
		return codeClassMap.get(req.getParameter("actioncode"));
	}
}